// wigets.h
#ifndef		WIDGETS_H
#define		WIDGETS_H

#include	"Node.h"
#include 	"GLCD.h"

#define		WIDGET_FL_REFRESH	0x0001
#define		WIDGET_FL_ENABLED	0x0004
#define		WIDGET_FL_SELECTED	0x0010
#define		WIDGET_FL_PRESSED	0x0020

extern struct sEvent eventDraw;
extern struct sEvent *WIDGET_EVENT_DRAW;


enum eEventSource{
	EVENT_SRC_KEYB = 0,
	EVENT_SRC_TOUCH,
	EVENT_SRC_UI,
	EVENT_SRC_MAX
};

enum eEventType{
	EVENT_TP_PRESS = 0,
	EVENT_TP_HOLD,
	EVENT_TP_RELEASE,
	EVENT_TP_DRAW,
	EVENT_TP_MAX
};

struct sEvent{
	enum eEventSource src;
	enum eEventType type;
	int16_t data1, data2;
};

enum eWidgetID{
	WIDGET_ID_CONTAINER = 0,
	WIDGET_ID_TEXT,
	WIDGET_ID_BUTTON,
	WIDGET_ID_MAX
};

struct sWidget{
	struct sNode node;
//	struct sWidget *pParent, *pChild, *pPrev, *pNext;
	enum eWidgetID ID;
	struct sRect rect;
	struct sGLCD *pGLCD;
	uint16_t flags;
	int16_t value;
		uint8_t state;
};

struct sWidgetContainer{
	struct sWidget widget;
};

struct sWidgetText{
	struct sWidget widget;
	const struct sFont *pFont;
	uint8_t *pStr;
};

struct sWidgetButton{
	struct sWidget widget;

	const struct sFont *pFont;
	char *pStr;
	const struct sBMP *pBMP;
	void (*pCBPress)( struct sWidgetButton *pButton );
	void (*pCBHold)( struct sWidgetButton *pButton );
	void (*pCBRelease)( struct sWidgetButton *pButton );
};

uint8_t WidgetAdd( struct sWidget *pWidget, struct sWidget *pNew );
uint8_t WidgetDel( struct sWidget *pWidget, struct sWidget *pOld );
uint8_t WidgetMove( struct sWidget *pWidget, struct sWidget *pMove );

uint8_t WidgetEvent( struct sWidget *pWidget, struct sEvent *pEvent );
uint8_t WidgetEventContainer( struct sWidget *pWidget, struct sEvent *pEvent );
uint8_t WidgetEventText( struct sWidget *pWidget, struct sEvent *pEvent );
uint8_t WidgetEventButton( struct sWidget *pWidget, struct sEvent *pEvent );

uint8_t	WidgetFlagTest( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagSet( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagClear( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagToggle( struct sWidget *pWidget, uint16_t flag );
/*
//void WidgetGenericEvent( struct sWidget *pWidget, const struct sEvent *pEvent ){
	switch( pEvent->source ){
		case EVENT_SRC_TOUCH:
			switch( pEvent->type ){
				case EVENT_TP_PRESS: 
					if( pWidget->x <= pEvent->x && pEvent->x <= pWidget->x + pWidget->w ){
						if( pWidget->y <= pEvent->y && pEvent->y <= pWidget->y + pWidget->h ){
							
						}
					}
					break;
				case EVENT_TP_HOLD: break;
				case EVENT_TP_RELEASE: break;
				default: break;
			}
			break;
		case EVENT_SRC_UI:
			GLCDRect( pWidget->pGLCD, pWidget->x, pWidget->y, pWidget->x + pWidget->w, pWidget->y + pWidget->h, GLCD_FILL, GLCD_COLOR_WHITE );
			break;
		default: break;
	}
}

//void WidgetTextEvent( struct sWidgetText *pText, const struct sEvent *pEvent ){
	if( WidgetTestFlag( &pText->widget, WIDGET_FL_ENABLED ) ){
		WidgetGenericEvent( &pText->widget, pEvent );
		switch( pEvent->source ){
			case EVENT_SRC_UI:
				GLCDText( pText->widget.pGLCD, pText->pFont, (char*)pText->pStr,
					pText->widget.x + pText->widget.w/2 - GLCDTextWidth( pText->pFont, pText->pStr )/2,
					pText->widget.y + pText->widget.h/2 - pText->pFont->height/2,
					GLCD_NO_INVERT, GLCD_NO_FILL, GLCD_COLOR_BLACK );
				break;
			default: break;
		}
	}
}


//void WidgetButtonEvent( struct sWidgetButton *pButton, const struct sEvent *pEvent ){
	if( WidgetTestFlag( &pButton->widget, WIDGET_FL_ENABLED ) ){
		WidgetGenericEvent( &pButton->widget, pEvent );
		switch( pEvent->source ){
			case EVENT_SRC_TOUCH:
				if( pWidget->x <= pEvent->x && pEvent->x <= pWidget->x + pWidget->w ){
					if( pWidget->y <= pEvent->y && pEvent->y <= pWidget->y + pWidget->h ){
						switch( pEvent->type ){
							case EVENT_TP_PRESS:	break;
							case EVENT_TP_HOLD:		break;
							case EVENT_TP_RELEASE:	break;
							break;
						}
					}
				}
				break;
			case EVENT_SRC_UI:
				if( WidgetFlagTest( &pButton->widget, WIDGET_FL_PRESSED ) ){
					GLCDRect( pButton->widget.pGLCD, 
						pButton->widget.x, 
						pButton->widget.y, 
						pButton->widget.x + pButton->widget.w,
						pButton->widget.y + pButton->widget.h,
						GLCD_FILL, GLCD_COLOR_BLACK );
				}
				if( NULL != pButton->pFont && NULL != pButton->pStr ){
					GLCDText( pButton->widget.pGLCD, pButton->pFont, (char*)pButton->pStr, 
						pButton->widget.x + pButton->widget.w/2 - GLCDTextWidth( pButton->pFont, pButton->pStr )/2, 
						pButton->widget.y + pButton->widget.h/2 - pButton->pFont->height/2, 
						GLCD_NO_INVERT, GLCD_NO_FILL, GLCD_COLOR_BLACK );
				}else if( NULL != pButton->pBMP ){
					GLCDDrawBMP( pButton->widget.pGLCD, pButton->pBMP, 
						pButton->widget.x + pButton->widget.w - pButton->pBMP->width/2,
						pButton->widget.y + pButton->widget.h - pButton->pBMP->height/2 );
				}
				break;
			default: break;
		}
	}
}

//void WidgetEvent( struct sWidget *pWidget, const struct sEvent *pEvent ){
	switch( pWidget->ID ){
		case WIDGET_ID_TEXT: 	WidgetTextEvent( pWidget, pEvent );		break;
		case WIDGET_ID_BUTTON:	WidgetButtonEvent( pWidget, pEvent );	break;
		default:	break;
	}
	
	if( NULL != pWidget->pChild ){
		WidgetEvent( pWidget->pChild, pEvent );
	}
	
	if( NULL != pWidget->pNext ){
		WidgetEvent( pWidget->pNext, pEvent );
	}
	return;
}



*/
/*
struct sWidgetTree{
	uint8_t scr, wdgt;
	struct sGLCD *pGLCD;
	struct sWidget[ SCREEN_MAX ][ WIDGETS_MAX ];
};


navigation

events

void preorden(tarbol *a)
{
  if (a != NULL) {
    visitar(a);
    preorden(a->izq);
    preorden(a->der);
  }
}

uint8_t eventPreorder( tree t, event e){
	if( NULL != t.next ){
		if( eventPreorder( tree t, event e) )
			return 1;
	}
	if( NULL != t.child ){
		if( eventPreorder( tree t, event e) )
			return 1;
	}
	switch( t.type ){
		case TEXTBOX:{
			return eventPreorder( tree t, event e) );
			break;
		}
		case BUTTON:{
			return eventPreorder( tree t, event e) );
			break;
		}
		default:{
			break;
		}
	}

	return 0;
}

struct swidgetContainer{
	struct sWidget widget;
	
}

visible
enabled
selected

setFLAGRecur(){
	if( NULL != t.next ){
		if( eventPreorder( tree t, event e) )
			return 1;
	}
	if( NULL != t.child ){
		if( eventPreorder( tree t, event e) )
			return 1;
	}
	t.flags |= FLAH_VISIBLE;
}
// Widgets flags test/change recuesivw
void	WidgetFlagRecursiveSet( struct sWidget *pWidget, uint16_t flag ){
	if( NULL != t.next ){
		WidgetFlagRecursiveSet( pWidget->next, flag );
	}
	if( NULL != t.child ){
		WidgetFlagRecursiveSet( pWidget->child, flag );
	}

	pWidget->flags |= flag;
	return;
}

void	WidgetFlagClear( struct sWidget *pWidget, uint16_t flag ){
	pWidget->flags &= ~flag;
	return;
}

void	WidgetFlagToggle( struct sWidget *pWidget, uint16_t flag ){
	pWidget->flags ^= flag;
	return;
}

*/
/*
struct sWidget{
	enum eWidgetID ID;
	uint16_t flags;
	int16_t value;
	struct sRect rect;
	struct sGLCD *pGLCD;
	struct sWidget *pParent, *pChild, *pNext, *pPrev;
};

struct sWidgetText{
	struct sWidget widget;
	const struct sFont *pFont;
	//uint8_t *pStr;
	char *pStr;
};

struct sWidgetImage{
	struct sWidget widget;
	const struct sBMP *pBMP;
};

struct sWidgetCheckBox{
	struct sWidget widget;
	void (*pfCallBackCheck)( struct sWidgetCheckBox *pCheckBox );
	void (*pfCallBackUncheck)( struct sWidgetCheckBox *pCheckBox );
};

struct sWidgetButton{
	struct sWidget widget;
	const struct sFont *pFont;
	//uint8_t *pStr;
	char *pStr;
	const struct sBMP *pBMP;
	void (*pfCallBackPress)( struct sWidgetButton *pButton );
//	void (*pfCallBackHold)( struct sWidgetButton *pButton );
	void (*pfCallBackRelease)( struct sWidgetButton *pButton );
};


// Widgets draw
//static void WidgetDrawGeneric( struct sWidget *pWidget );
//static void WidgetDrawRecursive( struct sWidget *pWidget, uint8_t next );
void	WidgetDraw( struct sWidget *pWidget );
void 	WidgetDrawText( struct sWidgetText *pText );
void	WidgetDrawImage( struct sWidgetImage *pImage );
void	WidgetDrawButton( struct sWidgetButton *pButton );
void	WidgetDrawCheckBox( struct sWidgetCheckBox *pCheckBox );

// widgets events
//static void WidgetEventGeneric( struct sWidget *pWidget, struct sWidgetEvent *pEvent );
//static void WidgetEventRecursive( struct sWidget *pWidget, struct sWidgetEvent *pEvent, uint8_t next );
void	WidgetEvent( struct sWidget *pWidget, struct sWidgetEvent *pEvent );
void	WidgetEventText( struct sWidgetText *pText, struct sWidgetEvent *pEvent );
void	WidgetEventImage( struct sWidgetImage *pImage, struct sWidgetEvent *pEvent );
void	WidgetEventButton( struct sWidgetButton *pButton, struct sWidgetEvent *pEvent );
void	WidgetEventCheckBox( struct sWidgetCheckBox *pCheckBox, struct sWidgetEvent *pEvent );

// Widgets flags test/change
uint8_t	WidgetFlagTest( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagSet( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagClear( struct sWidget *pWidget, uint16_t flag );
void	WidgetFlagToggle( struct sWidget *pWidget, uint16_t flag );

// Widgets navigate
uint8_t	WidgetNext( struct sWidget *pWidget );
uint8_t WidgetPrev( struct sWidget *pWidget );
uint8_t	WidgetParent( struct sWidget *pWidget );
uint8_t	WidgetChild( struct sWidget *pWidget );
void WidgetChangeSelected( struct sWidget *pWidget, struct sWidget *pWidgetNew );
uint8_t WidgetIsSelectable( struct sWidget *pWidget );
*/
#endif		//#ifndef		WIDGETS_H
